Polymorphism

Polymorphism denotes the capability of treating in similar fashion objects that belong to a class of types. Classwide types serve to denote objects that can belong dynamically to any derivation class.

<#510#>R1'Class<#510#> is a type that is implicitly defined when <#511#>R1<#511#> is defined, and which covers <#512#>R1<#512#> and all its extensions. All operations on <#513#>R1<#513#> can be applied to a value of type <#514#>R1'Class<#514#>.
The implementation of classwide types is delicate, because a value of such a type has an indefinite subtype, that is to say an unknown number of discriminants and unknown components beyond those inherited from <#515#>R1<#515#>. We have found it convenient to define a classwide type as an extension with unknown typeless storage. For instance, when the expression <#516#>new R1'Class (V)<#516#> is encountered, GNAT will the foloowing type

<#2768#>
verbatim137#
<#2768#>

There is another delicate point concerning the implementation of classwide types. All members of the class must have a compatible layout, so that offsets of corresponding components must be identical. This conflicts with the need to place discriminants at fixed offsets, usually at the beginning of the record, so as to be able to calculate the placement of components that depend on those discriminants. If any descendant can add new discriminants to a tagged type, it is not possible to make discriminants contiguous. Figure~#c1#524> shows the layout for the types of the previous example: we are forced to place <#525#>D3<#525#> and <#526#>D4<#526#> between <#527#>_parent<#527#> and the components <#528#>E1<#528#>, <#529#>En<#529#>.

<#2769#>Figure<#2769#>: <#2770#>Storage for classwide types<#2770#>
#figure530#